package com.mvc.portal.web;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.swing.tree.DefaultMutableTreeNode;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import com.mvc.base.service.NoticeManager;
import com.mvc.business.service.OrderManager;
import com.mvc.business.service.PurchaseManager;
import com.mvc.component.file.FileManager;
import com.mvc.finance.service.BankStatementManager;
import com.mvc.finance.service.CommercialInvoiceManager;
import com.mvc.finance.service.ExpenseApplyManager;
import com.mvc.framework.FrameworkConstants;
import com.mvc.framework.web.FrameworkFactory;
import com.mvc.portal.model.Theme;
import com.mvc.portal.service.MenuImageManager;
import com.mvc.portal.service.ThemeManager;
import com.mvc.security.SecurityConstants;
import com.mvc.security.model.Menu;

@Controller
@RequestMapping("/")
public class PortalController {

	private static final String	     PORTAL_DIR	= "portal/";
	private static final String	     COMMON_DIR	= "common/";
	private static final int	     HOME_PAGE	= -1;

	@Autowired
	private MenuImageManager	     menuImageManager;
	@Autowired
	private ThemeManager	         themeManager;

	@Autowired
	private NoticeManager	         noticeManager;

	@Autowired
	private OrderManager	         orderManager;

	@Autowired
	private PurchaseManager	         purchaseManager;
	@Autowired
	private ExpenseApplyManager	     expenseApplyManager;

	@Autowired
	private BankStatementManager	 bankStatementManager;
	@Autowired
	private CommercialInvoiceManager	commercialInvoiceManager;

	@RequestMapping(value = "main")
	public String main(HttpServletRequest request) throws Exception {
		setFirstLevelMenu(request);
		Object currentModuleId = request.getSession().getAttribute("currentModuleId");
		if (currentModuleId != null) {
			Integer moduleId = (Integer) currentModuleId;
			if (moduleId != HOME_PAGE) {
				// Side menu
				List<Menu> all = (List<Menu>) request.getSession().getAttribute(SecurityConstants.MENU_PERMISSION);
				DefaultMutableTreeNode tree = MenuUtils.getMenuTree(moduleId, all);
				Map<Menu, List<Menu>> sideMenus = new LinkedHashMap<Menu, List<Menu>>();
				if (tree.getChildCount() > 0) {
					Enumeration num = tree.children();
					while (num.hasMoreElements()) {
						DefaultMutableTreeNode node = (DefaultMutableTreeNode) num.nextElement();
						List<Menu> menus = new ArrayList<Menu>();
						Enumeration e = node.children();
						while (e.hasMoreElements()) {
							DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement();
							menus.add((Menu) n.getUserObject());
						}
						sideMenus.put((Menu) node.getUserObject(), menus);
					}
				}
				request.setAttribute("sideMenus", sideMenus);
				/*
				 * // Bread Crumbs Object currentMenuId =
				 * request.getSession().getAttribute("currentMenuId"); if
				 * (currentMenuId != null) { Integer menuId = (Integer)
				 * currentMenuId; List<Menu> breadCrumbs = new
				 * ArrayList<Menu>(); Menu leaf = getMenuByMenuId(all, menuId);
				 * MenuUtils.getParent(all, leaf, breadCrumbs);
				 * breadCrumbs.add(leaf); request.setAttribute("breadCrumbs",
				 * breadCrumbs); }
				 */
			}
		}
		return PORTAL_DIR + "main";
	}

	@RequestMapping(value = "index")
	public String index(HttpServletRequest request) throws Exception {
		request.getSession().setAttribute("currentModuleId", -1);
		request.setAttribute("notices", noticeManager.getValidNotices());
		request.setAttribute("needAuditOrder", orderManager.getNeedAuditCount());
		request.setAttribute("needAuditPurchase", purchaseManager.getNeedAuditCount());
		request.setAttribute("needAuditExpenseApply", expenseApplyManager.getNeedAuditCount());
		request.setAttribute("needAuditCommercialInvoice", commercialInvoiceManager.getNeedAuditCount());
		request.setAttribute("needAuditBankStatement", bankStatementManager.getNeedAuditCount());
		return PORTAL_DIR + "index";
	}

	@RequestMapping(value = "main/{moduleId}")
	public String module(HttpServletRequest request, @PathVariable Integer moduleId) throws Exception {
		request.getSession().setAttribute("currentModuleId", moduleId);
		return PORTAL_DIR + "sideMenu";
	}

	private void setFirstLevelMenu(HttpServletRequest request) {
		List<Menu> allPermissionMenus = (List<Menu>) request.getSession().getAttribute(SecurityConstants.MENU_PERMISSION);
		List<Menu> menus = MenuUtils.getFirstLevelMenu(allPermissionMenus);
		HttpSession session = request.getSession();
		session.setAttribute("menus", menus);
	}

	@RequestMapping(value = "wait/{menuId}")
	public String wait(HttpServletRequest request, @PathVariable Integer menuId) throws Exception {
		if (null != menuId) {
			List<Menu> allPermissionMenus = (List<Menu>) request.getSession().getAttribute(SecurityConstants.MENU_PERMISSION);
			Menu menu = getMenuByMenuId(allPermissionMenus, menuId);
			String forwardUrl = null;
			Menu top = MenuUtils.getTop(allPermissionMenus, menu);
			if (menu.getType() == Menu.TYPE_FOLDER) {
				List<Menu> subMenus = MenuUtils.getSubMenus(top.getObjectId(), allPermissionMenus);
				Menu first = null;
				for (Menu temp : subMenus) {
					if (temp.getType() == Menu.TYPE_MENU) {
						first = temp;
						break;
					}
				}
				forwardUrl = first.getFullUrl();
				request.getSession().setAttribute("currentMenuId", first.getObjectId());
			} else {
				forwardUrl = menu.getFullUrl();
				request.getSession().setAttribute("currentMenuId", menuId);
			}
			request.getSession().setAttribute("currentModuleId", top.getObjectId());
			request.setAttribute("forwardUrl", forwardUrl);
		}
		return PORTAL_DIR + "wait";
	}

	private Menu getMenuByMenuId(List<Menu> allPermissionMenus, long menuId) {
		for (Menu menu : allPermissionMenus) {
			if (menuId == menu.getObjectId()) {
				return menu;
			}
		}
		return null;
	}

	protected List<Menu> getMenusByModelName(List<Menu> allPermissionMenu, String modelName) {
		if (null == allPermissionMenu) {
			return new ArrayList<Menu>(0);
		}
		List<Menu> result = new ArrayList<Menu>();
		for (Menu menu : allPermissionMenu) {
			if (menu.getPath().startsWith(Menu.ROOT_CONTEXT + modelName)) {
				result.add(menu);
			}
		}
		return result;
	}

	@RequestMapping(value = "changeSkin/{color}")
	public String changeSkin(HttpServletRequest request, HttpServletResponse response, @PathVariable String color) throws Exception {
		if (color != null) {
			if ("d".equals(color) || "e".equals(color) || "f".equals(color) || "g".equals(color)) {
				HttpSession session = request.getSession();
				Theme theme = new Theme();
				theme.setSkin(color);
				theme.setUserId((Integer) session.getAttribute(SecurityConstants.USER_ID));
				themeManager.updateUserSkin(theme);
				session.setAttribute(FrameworkConstants.SKIN, color);
			}
		}
		return "redirect:../main";
	}

	@RequestMapping(value = "common/location/{menuId}")
	public String location(HttpServletRequest request, @PathVariable Long menuId, ModelMap modelMap) {
		List<Menu> allPermissionMenus = (List<Menu>) request.getSession().getAttribute(SecurityConstants.MENU_PERMISSION);
		List<Menu> tree = new ArrayList<Menu>();
		Menu leaf = getMenuByMenuId(allPermissionMenus, menuId);
		MenuUtils.getParent(allPermissionMenus, leaf, tree);
		tree.add(leaf);
		StringBuilder location = new StringBuilder(tree.size() * 6);
		for (Menu menu : tree) {
			location.append(" ").append(menu.getName()).append(" >> ");
		}
		modelMap.addAttribute("location", location.toString());
		return "";
	}

	@RequestMapping("download/{fileId}")
	public String download(@PathVariable String fileId, HttpServletResponse response) throws Exception {
		FileManager fileManager = FrameworkFactory.getFileManager();
		fileManager.download(Long.parseLong(fileId), response);
		return null;
	}
}
